package jp.ac.aiit.yc.sww.database;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;


import jp.ac.aiit.yc.sww.database.dao.*;
import jp.ac.aiit.yc.sww.database.dto.SwwDtoIF;

import java.sql.ResultSet;

public class DatabaseManager {

	private Connection connection;

	public DatabaseManager(){
		this.connection = null;
	}

	private Connection getConnection() throws SQLException{
		try {
			DBConnection dbCon= new DBConnection();
			this.connection = dbCon.getConnection();
			return this.connection;
		} catch (Exception e) {
			throw new SQLException("db connection error");
		}
	}


	public List<SwwDtoIF> getDto(SwwDtoIF dto, SwwDaoIF dao){
		//呼び出すプロシージャの設定
		String sp =dao.getQuerySP();
		System.out.println((new Date()).toString() + " dao.getQuerySP()=" + sp);
		List<SwwDtoIF> dtoList =  executeQuery(dto, dao, sp);
		return dtoList;
	}

	/**
	 * データをINSERTする
	 * */
	public boolean register(SwwDtoIF dto, SwwDaoIF dao ){
		//呼び出すプロシージャの設定
		String sp =dao.getInsertSP();
		System.out.println((new Date()).toString() + " dao.getInsertSP()=" + sp);
		return executeUpdate(dto, dao, sp);
	}

	/**
	 *
	 * */
	private List<SwwDtoIF> executeQuery(SwwDtoIF dto, SwwDaoIF dao, String procedure){
		boolean hadResults = false;
		CallableStatement cStmt =null;
		List<SwwDtoIF> dtoList = new ArrayList<SwwDtoIF>();
		try {
			// コネクションの取得
			this.connection = getConnection();
			//プロシージャステートメントの作成
			cStmt = this.connection.prepareCall(procedure);
			//プロシージャ引数の設定
			cStmt = dao.setQueryParam(cStmt, dto);
			//プロシージャ実行
			hadResults = cStmt.execute();
			System.out.println((new Date()).toString() + " " + procedure + "#execute()=" + hadResults);

			if(hadResults){
				ResultSet rs = cStmt.getResultSet();
				while(rs.next()){
					SwwDtoIF newDto = dao.createDto(rs);
					dtoList.add(newDto);
			      }
			}
		} catch (SQLException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (Exception e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}finally{
			try {
//				if(cStmt!=null && !cStmt.isClosed()){
				if(cStmt!=null){
					cStmt.close();
				}
			} catch (SQLException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
			try {
				if(this.connection!=null && !this.connection.isClosed()){
					this.connection.close();
				}
			} catch (SQLException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
		return dtoList;
	}

	/**
	 *
	 * */
	private boolean executeUpdate(SwwDtoIF dto, SwwDaoIF dao, String procedure){
		boolean result = false;
		CallableStatement cStmt =null;
		try {
			// コネクションの取得
			this.connection = getConnection();
			//プロシージャステートメントの作成
			cStmt = this.connection.prepareCall(procedure);
			//プロシージャ引数の設定
			cStmt = dao.setInsertParam(cStmt, dto);
			//プロシージャ実行
			result = cStmt.execute();
			System.out.println((new Date()).toString() + " " + procedure +  " execute()=" + result);
		} catch (SQLException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (Exception e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}finally{
			try {
//				if(cStmt!=null && !cStmt.isClosed()){
				if(cStmt!=null){
					cStmt.close();
				}
			} catch (SQLException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
			try {
				if(this.connection!=null && !this.connection.isClosed()){
					this.connection.close();
				}
			} catch (SQLException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
		}
		return result;
	}
}
